//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <RenderLibServer.h>

////////////////////////////////////////////////////////////////////////////
//                         ScanLine Render Utility                        //
////////////////////////////////////////////////////////////////////////////
Void ScanLineRGB24ToRGB24(
                Address destination, Address source, Int32 stride)
{
    Pixel *dst = (Pixel *)destination;
    Pixel *src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderRGB24ToRGB24((Address)dst, (Address)src);

        dst++;
        src++;
        stride--;
    }
}

Void ScanLineRGB24ToRGB24WithOpacity(
                Address destination, Address source, Int32 stride, UInt8 srcOpacity)
{
    assert(0xFF != srcOpacity && 0x00 != srcOpacity);

    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderRGB24ToRGB24WithOpacity((Address)dst, (Address)src, srcOpacity);

        src++;
        dst++;
        stride--;
    }
}
Void ScanLineARGB32ToRGB24(
                Address destination, Address source, Int32 stride)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToRGB24((Address)dst, (Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineARGB32ToRGB24WithOpacity(
                Address destination, Address source, Int32 stride, UInt8 srcOpacity)
{
    assert(0xFF != srcOpacity && 0x00 != srcOpacity);

    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToRGB24WithOpacity((Address)dst, (Address)src, srcOpacity);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineRGB24ToARGB32(
                Address destination, Address source, Int32 stride)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderRGB24ToARGB32((Address)dst, (Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineRGB24ToARGB32WithOpacity(
                Address destination, Address source, Int32 stride, UInt8 srcOpacity)
{
    assert(0xFF != srcOpacity && 0x00 != srcOpacity);

    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderRGB24ToARGB32WithOpacity((Address)dst, (Address)src, srcOpacity);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineARGB32ToARGB32(
                Address destination, Address source, Int32 stride)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineARGB32ToARGB32WithOpacity(
                Address destination, Address source, Int32 stride, UInt8 srcOpacity)
{
    assert(0xFF != srcOpacity && 0x00 != srcOpacity);

    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToARGB32WithOpacity((Address)dst, (Address)src, srcOpacity);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineA8ToRGB24(
                Address destination, Address src, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToRGB24((Address)dst, src, srcColor);

        src++;
        dst++;
        stride--;
    }
}
Void ScanLineA8ToRGB24WithColorAlpha(
                Address destination, Address src, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToRGB24WithColorAlpha((Address)dst, src, srcColor);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineA8ToARGB32(
                Address destination, Address src, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToARGB32((Address)dst, src, srcColor);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineA8ToARGB32WithColorAlpha(
                Address destination, Address src, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToARGB32WithColorAlpha((Address)dst, src, srcColor);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineSetColorARGB32(
                Address destination, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelSetColorARGB32((Address)dst, srcColor);

        dst++;
        stride--;
    }
}

Void ScanLineSetColorARGB32WithColorAlpha(
                Address destination, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelSetColorARGB32WithColorAlpha((Address)dst, srcColor);

        dst++;
        stride--;
    }
}


Void ScanLineRECT888To565(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16 *)destination;

    while (stride > 0) {
        *dst = Pixel888To565((Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineRECT888To565FLIP(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16 *)destination;

    while (stride > 0) {
        *--dst = Pixel888To565((Address)src);

        src++;
        stride--;
    }
}

Void ScanLineRECT888To565RCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16 *)destination;

    while (stride > 0) {
        *dst = Pixel888To565((Address)src);

        src++;
        dst = (UInt16*)((UInt8*)dst + dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To565RCCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16*)destination;

    while (stride > 0) {
        *dst = Pixel888To565((Address)src);

        src++;
        dst = (UInt16*)((UInt8*)dst - dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To666(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = Pixel888To666((Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineRECT888To666FLIP(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *--dst = Pixel888To666((Address)src);

        src++;
        stride--;
    }
}

Void ScanLineRECT888To666RCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = Pixel888To666((Address)src);

        src++;
        dst = (UInt32*)((UInt8*)dst + dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To666RCCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = Pixel888To666((Address)src);

        src++;
        dst = (UInt32*)((UInt8*)dst - dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To888FLIP(Address destination, Address source, Int32 stride)
{
    UInt32* src = (UInt32 *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *--dst = *src;

        src++;
        stride--;
    }
}

Void ScanLineRECT888To888RCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    UInt32* src = (UInt32 *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = *src;

        src++;
        dst = (UInt32*)((UInt8*)dst + dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To888RCCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    UInt32* src = (UInt32 *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = *src;

        src++;
        dst = (UInt32*)((UInt8*)dst - dstPitch);
        stride--;
    }
}


void ScanLeftAAEdge(Point ps, Point pe,
            ScanLineList * scanlinelist,
            int startY, int height,
            const BitmapBufInfo * srcImg, const BitmapBufInfo * dstImg)
{
	int dx=pe.x-ps.x;
	int dy=pe.y-ps.y;
	int xinc,yinc,i,x,y;
    Pixel *dst = NULL;
    Pixel *src = NULL;

	if (dx>0)
		xinc=1;
	else
		xinc=-1;

	if(dy>0)
		yinc=1;
	else
		yinc=-1;

	dx=abs(dx);
	dy=abs(dy);
	x=pe.x;
	y=pe.y;
	scanlinelist[y-startY].Left.x = x;
	scanlinelist[y-startY].Left.y = y;

    dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
    src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
    PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

	x=ps.x;
	y=ps.y;
	scanlinelist[y-startY].Left.x = x;
	scanlinelist[y-startY].Left.y = y;

    dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
    src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
    PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

	i=0;

	if(dx==0&&dy==0) {

        dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
        src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
        PixelRenderARGB32ToARGB32((Address)dst, (Address)src);
    }
	else if(dx==0)
	{
		for(i=0;i<dy;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

            scanlinelist[y-startY].Left.x = x;
            scanlinelist[y-startY].Left.y = y;
			y+=yinc;
		}
	}
	else if(dy==0)
	{
		for(i=0;i<dx;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);
			x+=xinc;
		}
	}
	else if(dx>dy)
	{
	    if (xinc>0) {
            _AAEDGEINFO aaedge;
    	    aaedge.s16 = y<<16;
            aaedge.d16 = (dy<<16)/dx;
            aaedge.startP = x;
            aaedge.deltaD = dx;
            aaedge.pDst = (UInt8*)dstImg->address;
            aaedge.pSrc = (UInt8*)srcImg->address;
            aaedge.nPitch = dstImg->pitch;
            aaedge.inc = xinc;
            aaedge.scanlinelist = scanlinelist;
            aaedge.startY = startY;
            DrawXMajorLPEdge(aaedge);
		}
		else {
            _AAEDGEINFO aaedge;
    	    aaedge.s16 = y<<16;
            aaedge.d16 = (dy<<16)/dx;
            aaedge.startP = x;
            aaedge.deltaD = dx;
            aaedge.pDst = (UInt8*)dstImg->address;
            aaedge.pSrc = (UInt8*)srcImg->address;
            aaedge.nPitch = dstImg->pitch;
            aaedge.inc = xinc;
            aaedge.scanlinelist = scanlinelist;
            aaedge.startY = startY;
            DrawXMajorLNEdge(aaedge);
	    }
    }
	else
	{
        _AAEDGEINFO aaedge;
	    aaedge.s16 = x<<16;
        aaedge.d16 = (dx<<16)/dy;
        if (xinc<0) {
           aaedge.d16=-aaedge.d16;
        }
        aaedge.startP = y;
        aaedge.deltaD = dy;
        aaedge.pDst = (UInt8*)dstImg->address;
        aaedge.pSrc = (UInt8*)srcImg->address;
        aaedge.nPitch = dstImg->pitch;
        aaedge.inc = yinc;
        aaedge.scanlinelist = scanlinelist;
        aaedge.startY = startY;
        DrawYMajorLEdge(aaedge);
	}
	return;
}

void ScanRightAAEdge(Point ps, Point pe,
            ScanLineList * scanlinelist,
            int startY, int height,
            const BitmapBufInfo * srcImg, const BitmapBufInfo * dstImg)
{
	int dx=pe.x-ps.x;
	int dy=pe.y-ps.y;
	int xinc,yinc,i,x,y;
    Pixel *dst = NULL;
    Pixel *src = NULL;

	if (dx>0)
		xinc=1;
	else
		xinc=-1;

	if(dy>0)
		yinc=1;
	else
		yinc=-1;

	dx=abs(dx);
	dy=abs(dy);

	x=pe.x;
	y=pe.y;
	scanlinelist[y-startY].Right.x = x;
	scanlinelist[y-startY].Right.y = y;

	x=ps.x;
	y=ps.y;
	scanlinelist[y-startY].Right.x = x;
	scanlinelist[y-startY].Right.y = y;

	i=0;

	if(dx==0&&dy==0) {
        dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
        src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
        PixelRenderARGB32ToARGB32((Address)dst, (Address)src);
	}
	else if(dx==0)
	{
		for(i=0;i<dy;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

            scanlinelist[y-startY].Right.x = x;
            scanlinelist[y-startY].Right.y = y;
			y+=yinc;
		}
	}
	else if(dy==0)
	{
		for(i=0;i<dx;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

			x+=xinc;
		}
	}
	else if(dx>dy)
	{
	    if (xinc>0) {
            _AAEDGEINFO aaedge;
    	    aaedge.s16 = y<<16;
            aaedge.d16 = (dy<<16)/dx;
            aaedge.startP = x;
            aaedge.deltaD = dx;
            aaedge.pDst = (UInt8*)dstImg->address;
            aaedge.pSrc = (UInt8*)srcImg->address;
            aaedge.nPitch = dstImg->pitch;
            aaedge.inc = xinc;
            aaedge.scanlinelist = scanlinelist;
            aaedge.startY = startY;
            DrawXMajorRPEdge(aaedge);
		}
		else {
            _AAEDGEINFO aaedge;
    	    aaedge.s16 = y<<16;
            aaedge.d16 = (dy<<16)/dx;
            aaedge.startP = x;
            aaedge.deltaD = dx;
            aaedge.pDst = (UInt8*)dstImg->address;
            aaedge.pSrc = (UInt8*)srcImg->address;
            aaedge.nPitch = dstImg->pitch;
            aaedge.inc = xinc;
            aaedge.scanlinelist = scanlinelist;
            aaedge.startY = startY;
            DrawXMajorRNEdge(aaedge);
		}
	}
	else
	{
        _AAEDGEINFO aaedge;
	    aaedge.s16 = x<<16;
        aaedge.d16 = (dx<<16)/dy;
        if (xinc<0) {
           aaedge.d16=-aaedge.d16;
        }
        aaedge.startP = y;
        aaedge.deltaD = dy;
        aaedge.pDst = (UInt8*)dstImg->address;
        aaedge.pSrc = (UInt8*)srcImg->address;
        aaedge.nPitch = dstImg->pitch;
        aaedge.inc = yinc;
        aaedge.scanlinelist = scanlinelist;
        aaedge.startY = startY;
        DrawYMajorREdge(aaedge);
	}
	return;
}
